home *** CD-ROM | disk | FTP | other *** search
/ Inter.Net 55-1 / Inter.Net 55-1.iso / beos / PPBeDevKit.ZIP / PLAYERPR.TAR / PlayerPRO / Source / Import-Export / MTM.c < prev    next >
Encoding:
C/C++ Source or Header  |  1998-12-26  |  12.2 KB  |  466 lines

  1. /********************                        ***********************/
  2. //
  3. //    Player PRO 5.0 - DRIVER SOURCE CODE -
  4. //
  5. //    Library Version 5.0
  6. //
  7. //    To use with MAD Library for Mac: Symantec, CodeWarrior and MPW
  8. //
  9. //    Antoine ROSSET
  10. //    16 Tranchees
  11. //    1206 GENEVA
  12. //    SWITZERLAND
  13. //
  14. //    COPYRIGHT ANTOINE ROSSET 1996, 1997, 1998
  15. //
  16. //    Thank you for your interest in PlayerPRO !
  17. //
  18. //    FAX:                (+41 22) 346 11 97
  19. //    PHONE:             (+41 79) 203 74 62
  20. //    Internet:     RossetAntoine@bluewin.ch
  21. //
  22. /********************                        ***********************/
  23.  
  24. #include "MTM.h"
  25. #include "MAD.h"
  26. #include "RDriver.h"
  27.  
  28. #if defined(powerc) || defined(__powerc)
  29. enum {
  30.         PlayerPROPlug = kCStackBased
  31.         | RESULT_SIZE(SIZE_CODE(sizeof(OSErr)))
  32.         | STACK_ROUTINE_PARAMETER(1, SIZE_CODE(sizeof( OSType)))
  33.         | STACK_ROUTINE_PARAMETER(2, SIZE_CODE(sizeof( Ptr)))
  34.         | STACK_ROUTINE_PARAMETER(3, SIZE_CODE(sizeof( MADMusic*)))
  35.         | STACK_ROUTINE_PARAMETER(4, SIZE_CODE(sizeof( PPInfoRec*)))
  36.         | STACK_ROUTINE_PARAMETER(5, SIZE_CODE(sizeof( MADDriverSettings*)))
  37. };
  38.  
  39. ProcInfoType __procinfo = PlayerPROPlug;
  40. #else
  41. #include <A4Stuff.h>
  42. #endif
  43.  
  44. Ptr MADPlugNewPtr( long size, MADDriverSettings* init)
  45. {
  46.     if( init->sysMemory) return NewPtrSys( size);
  47.     else return NewPtr( size);
  48. }
  49.  
  50. Ptr MADPlugNewPtrClear( long size, MADDriverSettings* init)
  51. {
  52.     if( init->sysMemory) return NewPtrSysClear( size);
  53.     else return NewPtrClear( size);
  54. }
  55.  
  56. Cmd* GetMADCommand( register short PosX, register short    TrackIdX, register PatData*    tempMusicPat)
  57. {
  58.     if( PosX < 0) PosX = 0;
  59.     else if( PosX >= tempMusicPat->header.size) PosX = tempMusicPat->header.size -1;
  60.         
  61.     return( & (tempMusicPat->Cmds[ (tempMusicPat->header.size * TrackIdX) + PosX]));
  62. }
  63.  
  64. void pStrcpy(register unsigned char *s1, register unsigned char *s2)
  65. {
  66.     register short len, i;
  67.     
  68.     len = *s2;
  69.     for ( i = 0; i <= len; i++) s1[ i] = s2[ i];
  70. }
  71.  
  72. void mystrcpy( Ptr a, Ptr b)
  73. {
  74.     BlockMove( b + 1, a, b[ 0]);
  75. }
  76.  
  77. unsigned long Tdecode32( void *msg_buf)
  78. {
  79.   unsigned char *buf = msg_buf;
  80.   
  81.   return( (unsigned long) buf[3] << 24) | ( (unsigned long) buf[2] << 16) | ( (unsigned long) buf[ 1] << 8) | ( (unsigned long) buf[0]);
  82. }
  83.  
  84. short Tdecode16( void *msg_buf)
  85. {
  86.   unsigned char *buf = msg_buf;
  87.   
  88.   return ( (short) buf[1] << 8) | ( (short) buf[0]);
  89. }
  90.  
  91.  
  92. struct MTMTrack* GetMTMCommand( short position, short whichTracks, Ptr PatPtr)
  93. {
  94.     Ptr                    aPtr;
  95.  
  96.     aPtr =     (    PatPtr +
  97.                 whichTracks * 192L +
  98.                 position * 3L);
  99.  
  100.     return (struct MTMTrack*) aPtr;
  101. }
  102.  
  103. OSErr ConvertMTM2Mad( MTMDef *MTMFile, long MTMSize, MADMusic *theMAD, MADDriverSettings *init)
  104. {
  105.     short             i, x, z;
  106.     long             sndSize, OffSetToSample, MPatSize, temp, inOutCount;
  107.     Ptr                MaxPtr;
  108.     OSErr            theErr;
  109.     Ptr                theInstrument[ 64], destPtr;
  110.     long             finetune[16] = 
  111.     {
  112.         8363,    8413,    8463,    8529,    8581,    8651,    8723,    8757,
  113.         7895,    7941,    7985,    8046,    8107,    8169,    8232,    8280
  114.     };
  115.     
  116.     /**** Variables pour le MAD ****/
  117.     Cmd                *aCmd;
  118.  
  119.     /**** Variables pour le MTM ****/
  120.     
  121.     struct Instru        *instru[ 64];
  122.     struct MTMTrack        *theCom;
  123.     Ptr                    samplePtr, patPtr, positionPtr;
  124.     short                *patTracks; 
  125.     /********************************/
  126.  
  127.     /**** Calcul de divers offsets *****/
  128.  
  129.     MTMFile->tracks = Tdecode16( &MTMFile->tracks);
  130.     MTMFile->comments = Tdecode16( &MTMFile->comments);
  131.     
  132.     MaxPtr         = (Ptr) ( (long)    MTMFile + MTMFile);
  133.     positionPtr    = (Ptr) ( (long)    MTMFile + 66L + MTMFile->NOS*37L);
  134.     patPtr         = (Ptr) ( (long)    MTMFile + 194L + MTMFile->NOS*37L);
  135.     destPtr        = (Ptr) ( (long)    MTMFile + 194L + MTMFile->NOS*37L + MTMFile->tracks*192L);
  136.     patTracks    = (short*) destPtr;
  137.     samplePtr     = (Ptr) ( (long)    MTMFile + 194L + MTMFile->NOS*37L + MTMFile->tracks*192L +
  138.                                     (MTMFile->patNo + 1L)*32L*2L + MTMFile->comments);
  139.     
  140.     /**** Analyse des instruments ****/
  141.     if( MTMFile->NOS > 64) return MADUnknowErr;
  142.     
  143.     for( i = 0, OffSetToSample = 0L; i < MTMFile->NOS ; i++)
  144.     {
  145.         theInstrument[ i] = samplePtr + OffSetToSample;
  146.  
  147.         instru[ i] = (struct Instru*) ((long) MTMFile + 66L + i*37L);
  148.  
  149.         instru[ i]->size = Tdecode32( &instru[ i]->size);
  150.         instru[ i]->loopBegin = Tdecode32( &instru[ i]->loopBegin);
  151.         instru[ i]->loopEnd = Tdecode32( &instru[ i]->loopEnd);
  152.  
  153.  
  154.         sndSize = instru[ i]->size;
  155.         if( theInstrument[i] + sndSize > MaxPtr)
  156.         {
  157.             // sndSize = instru[ i]->size = MaxPtr - theInstrument[i];
  158.             return MADUnknowErr;
  159.         }
  160.         OffSetToSample += sndSize;
  161.     }
  162.  
  163.  
  164.     /***********************************************/
  165.     /******** Le MTM a ÄtÄ lu et analysÄ ***********/
  166.     /***** Copie des informations dans le MAD ******/
  167.     /***********************************************/
  168.     
  169.     
  170.     
  171.     /**************************/
  172.     /*** MAD Initialisation ***/
  173.     /**************************/
  174.     
  175.     inOutCount = sizeof( MADSpec);
  176.     theMAD->header = (MADSpec*) MADPlugNewPtrClear( inOutCount, init);    
  177.     if( theMAD->header == 0L) return MADNeedMemory;
  178.     theMAD->header->MAD = 'MADI';
  179.     
  180.     /*****************************************/
  181.     /*** Copie des informations MTM -> MAD ***/
  182.     /*****************************************/
  183.     
  184.     for(i=0; i<22; i++)
  185.     {
  186.         theMAD->header->name[i] = MTMFile->songname[i];
  187.     }
  188.     
  189.     mystrcpy( theMAD->header->infos, (Ptr) "\pConverted by PlayerPRO MTM Plug (⌐Antoine ROSSET <rossetantoine@bluewin.ch>)");
  190.     
  191.     theMAD->header->tempo = 125;
  192.     theMAD->header->speed = 6;
  193.     theMAD->header->numPat                 = MTMFile->patNo + 1;
  194.     theMAD->header->numPointers            = MTMFile->positionNo;
  195.     for(i=0; i<128; i++)
  196.     {
  197.         theMAD->header->oPointers[ i]     = positionPtr[ i];
  198.     }
  199.     theMAD->header->numChn                 = MTMFile->trackback;
  200.     
  201.     for( i = 0; i < MAXTRACK; i++)
  202. {
  203.     if( i % 2 == 0) theMAD->header->chanPan[ i] = MAX_PANNING/4;
  204.     else theMAD->header->chanPan[ i] = MAX_PANNING - MAX_PANNING/4;
  205.     
  206.     theMAD->header->chanVol[ i] = MAX_VOLUME;
  207. }
  208.     theMAD->header->generalVol        = 64;
  209.     theMAD->header->generalSpeed    = 80;
  210.     theMAD->header->generalPitch    = 80;
  211.  
  212.     
  213.     // INSTRUMENTS
  214.     
  215.     theMAD->fid = ( InstrData*) MADPlugNewPtrClear( sizeof( InstrData) * (long) MAXINSTRU, init);
  216.     if( !theMAD->fid) return MADNeedMemory;
  217.     
  218.     theMAD->sample = ( sData**) MADPlugNewPtrClear( sizeof( sData*) * (long) MAXINSTRU * (long) MAXSAMPLE, init);
  219.     if( !theMAD->sample) return MADNeedMemory;
  220.     
  221.     for( i = 0; i < MAXINSTRU; i++) theMAD->fid[ i].firstSample = i * MAXSAMPLE;
  222.     
  223.     for(i = 0; i < MTMFile->NOS; i++)
  224.     {
  225.         for( x = 0; x < 22; x++) theMAD->fid[i].name[x] = instru[i]->name[x];
  226.         theMAD->fid[i].type = 0;
  227.         
  228.         if( instru[ i]->size > 0)
  229.         {
  230.             sData    *curData;
  231.             
  232.             theMAD->fid[i].numSamples = 1;
  233.             theMAD->fid[i].volFade = DEFAULT_VOLFADE;
  234.             
  235.             curData = theMAD->sample[ i*MAXSAMPLE + 0] = (sData*) MADPlugNewPtrClear( sizeof( sData), init);
  236.             
  237.             curData->size        = instru[ i]->size;
  238.             curData->loopBeg     = instru[ i]->loopBegin;
  239.             curData->loopSize     = instru[ i]->loopEnd - instru[i]->loopBegin;
  240.             curData->vol        = instru[ i]->volume;
  241.             curData->c2spd        = finetune[ instru[ i]->fineTune];
  242.             curData->loopType    = 0;
  243.             curData->amp        = 8;
  244.             
  245.             curData->relNote    = 0;
  246.         //    for( x = 0; x < 22; x++) curData->name[x] = instru[i]->name[x];
  247.             
  248.             curData->data         = MADPlugNewPtr( curData->size, init);
  249.             if( curData->data == 0L) DebugStr("\pInstruments: I NEED MEMORY !!! NOW !");
  250.             
  251.             BlockMove( theInstrument[i], curData->data, curData->size);
  252.             
  253.             destPtr = curData->data;
  254.             for( temp = 0; temp < curData->size; temp++) *(destPtr + temp) -= 0x80;
  255.         }
  256.         else theMAD->fid[ i].numSamples = 0;
  257.     }
  258.     
  259.     for(i=0; i<theMAD->header->numPat; i++)
  260.     {
  261.         
  262.         theMAD->partition[ i] = (PatData*) MADPlugNewPtrClear( sizeof( PatHeader) + theMAD->header->numChn * 64L * sizeof( Cmd), init);
  263.         if( theMAD->partition[ i] == 0L) return MADNeedMemory;
  264.  
  265.         theMAD->partition[ i]->header.size = 64L;
  266.         theMAD->partition[ i]->header.compMode = 'NONE';
  267.  
  268.         for( x = 0; x < 20; x++) theMAD->partition[ i]->header.name[ x] = 0;
  269.  
  270.         theMAD->partition[ i]->header.patBytes = 0L;
  271.         theMAD->partition[ i]->header.unused2 = 0L;
  272.  
  273.         MaxPtr = (Ptr) theMAD->partition[ i];
  274.         MaxPtr += sizeof( PatHeader) + theMAD->header->numChn * 64L * sizeof( Cmd);
  275.  
  276.         for( z = 0; z < 32; z++) patTracks[ z] = Tdecode16( &patTracks[ z]);
  277.  
  278.         for(x=0; x<64; x++)
  279.         {
  280.             for(z=0; z<theMAD->header->numChn; z++)
  281.             {
  282.                 aCmd = GetMADCommand(  x,  z, theMAD->partition[ i]);
  283.                 if( (Ptr) aCmd + sizeof( Cmd) > MaxPtr) return MADUnknowErr;
  284.                 
  285.                 if( patTracks[ z] == 0)
  286.                 {
  287.                     aCmd->ins        = 0;
  288.                     aCmd->note        = 0xFF;
  289.                     aCmd->cmd        = 0;
  290.                     aCmd->arg        = 0;
  291.                     aCmd->vol        = 0xFF;
  292.                 }
  293.                 else
  294.                 {
  295.                     theCom         = GetMTMCommand(    x,
  296.                                                     patTracks[ z],
  297.                                                     (Ptr) patPtr);
  298.                     
  299.                     aCmd->ins     = theCom->instru;
  300.                     
  301.                     if( theCom->pitch)
  302.                     {
  303.                         aCmd->note     = theCom->pitch + 22;
  304.                     }
  305.                     else aCmd->note = 0xFF;
  306.                     
  307.                     aCmd->cmd     = theCom->EffectCmd;
  308.                     aCmd->arg     = theCom->EffectArg;
  309.                     aCmd->vol    = 0xFF;
  310.                 }
  311.             }
  312.         }
  313.         
  314.         /*** Avance dans les tracks-patterns suivants ***/
  315.         patTracks += 32;
  316.     }
  317.     
  318.     return noErr;
  319. }
  320.  
  321. OSErr ExtractInfo( PPInfoRec *info, MTMDef *myFile)
  322. {
  323.     long    PatternSize;
  324.     short    i;
  325.     short    maxInstru;
  326.     short    tracksNo;
  327.     
  328.     for( i = 0; i < sizeof( myFile->songname); i++)
  329.     {
  330.         info->internalFileName[ i] = myFile->songname[ i];
  331.     }
  332.     info->internalFileName[ 21] = 0;
  333.     CtoPstr( (Ptr) info->internalFileName);
  334.  
  335.     MADstrcpy( info->formatDescription, "MTM Plug");
  336.  
  337.     info->totalPatterns        = myFile->patNo;
  338.     info->partitionLength    = myFile->positionNo;
  339.     info->totalTracks        = myFile->tracks;
  340.     info->totalInstruments    = myFile->NOS;
  341.     info->signature            = 'MTM ';
  342.  
  343.     return noErr;
  344. }
  345.  
  346. OSErr TestFile( MTMDef *myFile)
  347. {    
  348.     if(    myFile->Id[ 0] == 'M' &&
  349.         myFile->Id[ 1] == 'T' &&
  350.         myFile->Id[ 2] == 'M') return noErr;
  351.         
  352.     else return MADFileNotSupportedByThisPlug;
  353. }
  354.  
  355. /*****************/
  356. /* MAIN FUNCTION */
  357. /*****************/
  358.  
  359. OSErr main( OSType order, Ptr AlienFileName, MADMusic *MadFile, PPInfoRec *info, MADDriverSettings *init)
  360. {
  361.     OSErr    myErr;
  362.     Ptr        AlienFile;
  363.     short    iFileRefI;
  364.     long    sndSize;
  365.     
  366. #ifndef powerc
  367.     long    oldA4 = SetCurrentA4();             //this call is necessary for strings in 68k code resources
  368. #endif
  369.     
  370.     c2pstr( AlienFileName);
  371.     
  372.     myErr = noErr;
  373.     
  374.     switch( order)
  375.     {
  376.         case 'IMPL':
  377.             myErr = FSOpen( (unsigned char*) AlienFileName, 0, &iFileRefI);
  378.             if( myErr == noErr)
  379.             {
  380.                 GetEOF( iFileRefI, &sndSize);
  381.             
  382.                 // ** TEST MEMOIRE :  Environ 2 fois la taille du fichier**
  383.                 AlienFile = MADPlugNewPtr( sndSize * 2L, init);
  384.                 if( AlienFile == 0L) myErr = MADNeedMemory;
  385.                 // ** 
  386.                 
  387.                 else
  388.                 {
  389.                     DisposePtr( AlienFile);
  390.                     
  391.                     AlienFile = MADPlugNewPtr( sndSize, init);
  392.                     myErr = FSRead( iFileRefI, &sndSize, AlienFile);
  393.                     if( myErr == noErr)
  394.                     {
  395.                         myErr = TestFile( (MTMDef*) AlienFile);
  396.                         if( myErr == noErr)
  397.                         {
  398.                             myErr = ConvertMTM2Mad( (MTMDef*) AlienFile, GetPtrSize( AlienFile), MadFile, init);
  399.                         }
  400.                     }
  401.                     DisposePtr( AlienFile);    AlienFile = 0L;
  402.                 }
  403.                 FSClose( iFileRefI);
  404.             }
  405.         break;
  406.         
  407.         case 'TEST':
  408.             myErr = FSOpen( (unsigned char*) AlienFileName, 0, &iFileRefI);
  409.             if( myErr == noErr)
  410.             {
  411.                 sndSize = 5000L;    // Read only 5000 first bytes for optimisation
  412.                 
  413.                 AlienFile = MADPlugNewPtr( sndSize, init);
  414.                 if( AlienFile == 0L) myErr = MADNeedMemory;
  415.                 else
  416.                 {
  417.                     myErr = FSRead( iFileRefI, &sndSize, AlienFile);
  418.                     if( myErr == noErr)
  419.                     {
  420.                         myErr = TestFile( (MTMDef*) AlienFile);
  421.                     }
  422.                     DisposePtr( AlienFile);    AlienFile = 0L;
  423.                 }
  424.                 FSClose( iFileRefI);
  425.             }
  426.         break;
  427.         
  428.         case 'EXPL':
  429.             myErr = MADOrderNotImplemented;
  430.         break;
  431.  
  432.         case 'INFO':
  433.             myErr = FSOpen( (unsigned char*) AlienFileName, 0, &iFileRefI);
  434.             if( myErr == noErr)
  435.             {
  436.                 GetEOF( iFileRefI, &info->fileSize);
  437.             
  438.                 sndSize = 5000L;    // Read only 5000 first bytes for optimisation
  439.                 
  440.                 AlienFile = MADPlugNewPtr( sndSize, init);
  441.                 if( AlienFile == 0L) myErr = MADNeedMemory;
  442.                 else
  443.                 {
  444.                     myErr = FSRead( iFileRefI, &sndSize, AlienFile);
  445.                     if( myErr == noErr)
  446.                     {
  447.                         myErr = ExtractInfo( info, (MTMDef*) AlienFile);
  448.                     }
  449.                     DisposePtr( AlienFile);    AlienFile = 0L;
  450.                 }
  451.                 FSClose( iFileRefI);
  452.             }
  453.         break;
  454.         
  455.         default:
  456.             myErr = MADOrderNotImplemented;
  457.         break;
  458.     }
  459.     
  460.     p2cstr( (unsigned char*) AlienFileName);
  461.     
  462.     #ifndef powerc
  463.         SetA4( oldA4);
  464.     #endif
  465.     return myErr;
  466. }